<template>
  <div class="mapWrapper">
    <div class="mapContainer" id="mapContainer"></div>
  </div>
</template>

<script setup>
import AMapLoader from '@amap/amap-jsapi-loader'
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import { elRectification } from 'autofit.js'

const props = defineProps({
  stationData: {
    type: Array,
    default: () => []
  }
})

let map = null
let cluster = null

// 添加全局变量存储当前打开的信息窗体
let currentInfoWindow = null

// 处理站点数据，生成地图所需的格式
const processStationData = (data) => {
  const points = data.map((item) => ({
    lnglat: [item.stationLng, item.stationLat],
    name: item.stationName,
    id: item.stationId,
    province: item.province,
    city: item.city,
    district: item.district,
    station: item.stationName, // 添加站点名称作为最后一级
    stationLng: item.stationLng,
    stationLat: item.stationLat,
    stationManager: item.stationManager,
    stationTel: item.stationTel,
    number: item.number
  }))

  // 生成区域中心点数据
  const districts = {}
  const cities = {}
  const provinces = {}

  data.forEach((item) => {
    // 区级中心点
    if (!districts[item.district]) {
      districts[item.district] = {
        center: `${item.stationLng},${item.stationLat}`,
        count: 1
      }
    } else {
      districts[item.district].count++
    }

    // 市级中心点
    if (!cities[item.city]) {
      cities[item.city] = {
        center: `${item.stationLng},${item.stationLat}`,
        count: 1
      }
    } else {
      cities[item.city].count++
    }

    // 省级中心点
    if (!provinces[item.province]) {
      provinces[item.province] = {
        center: `${item.stationLng},${item.stationLat}`,
        count: 1
      }
    } else {
      provinces[item.province].count++
    }
  })

  return {
    points,
    districts,
    cities,
    provinces
  }
}

const clusterIndexSet = {
  province: {
    // 省级层级
    minZoom: 2,
    maxZoom: 6
  },
  city: {
    // 市级层级
    minZoom: 6,
    maxZoom: 8
  },
  district: {
    // 区级层级
    minZoom: 8,
    maxZoom: 10
  },
  station: {
    // 站点层级
    minZoom: 10,
    maxZoom: 22
  }
}

function getStyle(context) {
  const clusterData = context.clusterData
  const index = context.index
  const count = context.count
  const color = ['8,60,156', '66,130,198', '107,174,214', '78,200,211']
  const indexs = ['province', 'city', 'district', 'station']
  const i = indexs.indexOf(index['mainKey'])
  const text = clusterData[0][index['mainKey']]

  // 计算文字宽度（调整字符宽度基准值）
  const getTextWidth = (str) => {
    return str.split('').reduce((width, char) => {
      return width + (/[\u4e00-\u9fa5]/.test(char) ? 9 : 4)
    }, 0)
  }

  let finalText = text
  let size
  if (i <= 2) {
    // 省市区层级
    const nameText = `<span class="showName">${text}</span>`
    const countText = `<span class="showCount">${count}个站点</span>`
    finalText = nameText + countText
    // 调整基础大小和计算方式
    const textWidth = getTextWidth(text + count + '个站点')
    size = Math.max(textWidth + 12, Math.round(12 + Math.pow(count / props.stationData.length, 1 / 8) * 20))
  } else {
    // 站点层级
    finalText = `<span class="showName station-name">${clusterData[0].name}</span>`
    const textWidth = getTextWidth(clusterData[0].name)
    size = textWidth + 48 // 标签形式的宽度
  }

  return {
    bgColor: `rgba(${color[i]},.8)`,
    borderColor: `rgba(${color[i]},1)`,
    text: finalText,
    size: size,
    index: i,
    color: '#ffffff',
    textAlign: 'center',
    boxShadow: '0px 0px 5px rgba(0,0,0,0.8)'
  }
}

function getPosition(context) {
  const { districts, cities, provinces } = processStationData(props.stationData)
  const key = context.index.mainKey
  const dataItem = context.clusterData && context.clusterData[0]
  const name = dataItem[key]

  let centerData
  switch (key) {
    case 'province':
      centerData = provinces[name]
      break
    case 'city':
      centerData = cities[name]
      break
    case 'district':
      centerData = districts[name]
      break
    default:
      return null
  }

  if (!centerData) return null

  const center = centerData.center.split(',')
  return new AMap.LngLat(center[0], center[1])
}

function _renderClusterMarker(context) {
  const styleObj = getStyle(context)
  const div = document.createElement('div')
  div.className = 'amap-cluster'
  div.style.backgroundColor = styleObj.bgColor
  div.style.width = styleObj.size + 'px'

  if (styleObj.index <= 2) {
    // 省市区层级保持圆形
    div.style.height = styleObj.size + 'px'
    div.style.borderRadius = styleObj.size + 'px'
  } else {
    // 站点层级使用圆角标签样式
    div.className = 'amap-cluster station-marker'
    div.style.height = '32px' // 固定高度
    div.style.borderRadius = '16px' // 半圆角
  }

  context.marker.on('click', function (e) {
    // 关闭已打开的信息窗体
    if (currentInfoWindow) {
      currentInfoWindow.close()
      currentInfoWindow = null
    }

    if (styleObj.index <= 2) {
      let curZoom = map.getZoom()
      if (curZoom < 20) {
        curZoom += 3
      }
      map.setZoomAndCenter(curZoom, e.lnglat)
    } else {
      // 站点层级点击事件处理
      const station = context.clusterData[0]

      const info = document.createElement('div')
      info.className = 'station-info'
      info.innerHTML = `
        <div class="info-header">
          <h4>${station.name}</h4>
          <span class="info-id">ID: ${station.id}</span>
        </div>
        <div class="info-content">
          <div class="info-item">
            <span>区域：</span>
            <span>${station.province} ${station.city} ${station.district}</span>
          </div>
          <div class="info-item">
            <span>经纬度：</span>
            <span>${station.stationLng?.toFixed(6) || '-'}，${station.stationLat?.toFixed(6) || '-'}</span>
          </div>
          <div class="info-item">
            <span>联系电话：</span>
            <span>${station.stationTel || '-'}</span>
          </div>
          <div class="info-item">
            <span>负责人：</span>
            <span>${station.stationManager || '-'}</span>
          </div>
           <div class="info-item">
            <span>设备数：</span>
            <span>${station.number || '-'}</span>
          </div>

        </div>
      `

      const infoWindow = new AMap.InfoWindow({
        content: info,
        offset: new AMap.Pixel(0, -30),
        closeWhenClickMap: true,
        isCustom: true
      })

      currentInfoWindow = infoWindow
      infoWindow.open(map, e.lnglat)
    }
  })

  div.style.border = `solid 1px ${styleObj.borderColor}`
  div.innerHTML = styleObj.text
  div.style.color = styleObj.color
  div.style.textAlign = styleObj.textAlign
  div.style.boxShadow = styleObj.boxShadow
  context.marker.setContent(div)

  const position = getPosition(context)
  if (position) {
    context.marker.setPosition(position)
  }
  context.marker.setAnchor('center')
}

// 初始化地图
const initMap = async () => {
  window._AMapSecurityConfig = {
    securityJsCode: 'a57bb63d1bab0fabcab469adba9f426c'
  }

  const AMap = await AMapLoader.load({
    key: '53ed0523f35af95f296ce0c5b360d960',
    version: '2.0',
    plugins: ['AMap.IndexCluster'],
    zooms: [16, 22]
  })

  elRectification('.mapContainer', true, 1)

  map = new AMap.Map('mapContainer', {
    zoom: 4, // 调整初始缩放级别以显示全国
    center: [104.5, 38.5], // 设置地图中心点为全国中心
    animateEnable: true,
    mapStyle: 'amap://styles/grey',
    zooms: [3, 22]
  })

  // 添加地图事件监听
  map.on('zoomstart', () => {
    if (currentInfoWindow) {
      currentInfoWindow.close()
      currentInfoWindow = null
    }
  })

  if (props.stationData.length > 0) {
    const { points } = processStationData(props.stationData)
    cluster = new AMap.IndexCluster(map, points, {
      renderClusterMarker: _renderClusterMarker,
      clusterIndexSet: clusterIndexSet
    })
  }
}

// 监听数据变化
watch(
  () => props.stationData,
  (newData) => {
    if (map && newData.length > 0) {
      const { points } = processStationData(newData)
      if (cluster) {
        cluster.setData(points)
      } else {
        cluster = new AMap.IndexCluster(map, points, {
          renderClusterMarker: _renderClusterMarker,
          clusterIndexSet: clusterIndexSet
        })
      }
    }
  },
  { deep: true }
)

onMounted(() => {
  initMap()
})

onBeforeUnmount(() => {
  if (map) {
    map.destroy()
    map = null
  }
})
</script>

<style scoped>
.mapWrapper {
  width: 100%;
  height: 100%;
  position: relative;
}
.mapContainer {
  width: 100%;
  height: 100%;
  position: relative;
}

:deep(.amap-cluster) {
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  font-size: 12px;
  padding: 3px;
  box-sizing: border-box;
  min-width: 32px;
  min-height: 32px;
}

:deep(.station-marker) {
  width: auto !important;
  flex-direction: row !important;
  padding: 0 16px !important;
  height: 32px !important;
  background: rgba(24, 144, 255, 0.9) !important;
  border: 1px solid rgba(24, 144, 255, 1) !important;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2) !important;
}

:deep(.station-marker .station-name) {
  font-size: 13px !important;
  padding: 0 !important;
  font-weight: normal !important;
  line-height: 32px !important;
  color: #fff !important;
}

:deep(.showName) {
  font-size: 13px;
  white-space: nowrap;
  line-height: 1.2;
}

:deep(.showCount) {
  font-size: 11px;
  white-space: nowrap;
  margin-top: 1px;
  opacity: 0.8;
}

:deep(.station-info) {
  padding: 0;
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 8px;
  min-width: 280px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.1);
}

:deep(.info-header) {
  padding: 12px 16px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

:deep(.info-header h4) {
  margin: 0;
  font-size: 16px;
  color: #1890ff;
  font-weight: 500;
}

:deep(.info-id) {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.6);
}

:deep(.info-content) {
  padding: 12px 16px;
}

:deep(.info-item) {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
  font-size: 13px;
}

:deep(.info-item:last-child) {
  margin-bottom: 0;
}
</style>
